import { Model, Effect } from "dva-core-ts";
import { Reducer } from "redux";
import {
  getProductSuccess,
  GET_PRODUCT,
  GET_PRODUCT_SUCCESS,
  searchProductSuccess,
  SEARCH_PRODUCT_SUCCESS,
} from "./action";
import { Product } from "./dto";
import { handleProductSearchService, handleProductService } from "./service";

export interface ProductState {
  createdAt: {
    loaded: boolean;
    success: boolean;
    products: Array<Product>;
  };
  sold: {
    loaded: boolean;
    success: boolean;
    products: Array<Product>;
  };
  search: Array<Product>;
}

const initialState: ProductState = {
  createdAt: {
    loaded: false,
    success: false,
    products: [],
  },
  sold: {
    loaded: false,
    success: false,
    products: [],
  },
  search: [],
};
const handleProduct = "handleProduct";
const handleProductSearch = "handleProductSearch";

export const PRODUCT_EFFECT = {
  handleProduct: "product/" + handleProduct,
  handleProductSearch: "product/" + handleProductSearch,
};
interface ProductModel extends Model {
  namespace: "product";
  state: ProductState;
  reducers: {
    setState: Reducer<ProductState>;
  };
  effects: {
    [handleProduct]: Effect;
    [handleProductSearch]: Effect;
  };
}
const productModel: ProductModel = {
  namespace: "product",
  state: initialState,
  reducers: {
    setState(state = initialState, { payload }) {
      console.log(payload);

      switch (payload.type) {
        case GET_PRODUCT:
          return {
            ...state,
            [payload.sortBy]: {
              ...state[payload.sortBy === "createdAt" ? "createdAt" : "sold"],
              loaded: false,
              success: false,
              // products: [],
            },
          };
        case GET_PRODUCT_SUCCESS:
          return {
            ...state,
            [payload.sortBy]: {
              loaded: true,
              success: true,
              products: payload.payload,
            },
          };
        case SEARCH_PRODUCT_SUCCESS:
          return {
            ...state,
            search: payload.payload.products,
          };
        default:
          return {
            ...state,
          };
      }
    },
  },
  effects: {
    *[handleProduct]({ payload }, { call, put }) {
      let res;
      try {
        res = yield call(handleProductService, payload);
        console.log(handleProduct, res);
        yield put({
          type: "setState",
          payload: getProductSuccess(res.data, payload.sortBy),
        });
      } catch (error) {
        console.log(error);
      }
    },
    *[handleProductSearch]({ payload }, { call, put }) {
      console.log(payload);
      let res;
      try {
        res = yield call(handleProductSearchService, payload);
        console.log(handleProductSearch, res);
        yield put({
          type: "setState",
          payload: searchProductSuccess(res.data),
        });
      } catch (error) {
        console.log(error);
      }
    },
  },
};

export default productModel;
